package xiaojian.toolkit.netty.handler.codec.http.transformer;

import io.netty.handler.codec.http.FullHttpRequest;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.Transformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xiaojian.toolkit.util.DynaBeanUtils;
import xiaojian.toolkit.util.MutablePropertyable;
import xiaojian.toolkit.util.Propertyable;
import xiaojian.toolkit.util.PropertyableUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

/**
 * @author hp
 *
 */
public class CopyRequestPropertyTransformer implements HttpRequestTransformer {

	private static final Logger logger = LoggerFactory
			.getLogger(CopyRequestPropertyTransformer.class);

	private Transformer impl;
	private String[] copyedProperties;
	private String propertyHttpRequest;
	private boolean useLazyBean = true;

	public boolean isUseLazyBean() {
		return useLazyBean;
	}

	public void setUseLazyBean(boolean useLazyBean) {
		this.useLazyBean = useLazyBean;
	}

	public String getPropertyHttpRequest() {
		return propertyHttpRequest;
	}

	public void setPropertyHttpRequest(String propertyHttpRequest) {
		this.propertyHttpRequest = propertyHttpRequest;
	}

	/**
	 * @param impl
	 *            the impl to set
	 */
	public void setImpl(Transformer impl) {
		this.impl = impl;
	}

	public void setCopyedProperties(List<String> propertyNames) {
		this.copyedProperties = propertyNames.toArray(new String[propertyNames
				.size()]);
	}

	public List<String> getCopyedProperties() {
		return Arrays.asList(copyedProperties);
	}

	@Override
	public Object transform(FullHttpRequest request) {
		Object bean = impl.transform(request);
		if (null == bean) {
			return null;
		}

		if (bean instanceof MutablePropertyable) {

			PropertyableUtils.copyProperties((Propertyable) request,
					(MutablePropertyable) bean, copyedProperties);
			((MutablePropertyable) bean).setProperty(propertyHttpRequest,
					request);
		} else {
			if (this.useLazyBean) {
				bean = DynaBeanUtils.wrapLazyDynaBean(bean);
			}

			try {
				PropertyUtils.setProperty(bean, propertyHttpRequest, request);

			} catch (IllegalAccessException e) {
				logger.error("copy property:", e);
			} catch (InvocationTargetException e) {
				logger.error("copy property:", e);
			} catch (NoSuchMethodException e) {
				logger.error("copy property:", e);
			}

			Propertyable propertyable = (Propertyable) request;
			if (null != propertyable) {
				for (String name : copyedProperties) {
					try {
						PropertyUtils.setProperty(bean, name,
								propertyable.getProperty(name));
					} catch (IllegalAccessException e) {
						logger.error("copy property:", e);
					} catch (InvocationTargetException e) {
						logger.error("copy property:", e);
					} catch (NoSuchMethodException e) {
						logger.error("copy property:", e);
					}
				}
			}
		}

		return bean;
	}

}
